package com.qf.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.qf.api.entity.SysMenuEntity;
import com.qf.api.entity.SysRoleEntity;
import com.qf.api.service.SysMenuService;
import com.qf.api.vo.MenuVO;
import com.qf.api.vo.RouteVO;
import com.qf.dao.mapper.SysMenuMapper;
import jakarta.annotation.Resource;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;

import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import java.util.stream.Collectors;

/**
 * @Author: sin
 * @Date: 2025/5/7 15:26
 * @Description:
 **/
@Service
@Slf4j
public class SysMenuServiceImpl extends ServiceImpl<SysMenuMapper, SysMenuEntity>
        implements SysMenuService {

    @Resource
    private SysMenuMapper menuMapper;


    @Override
    public List<RouteVO> buildRouterTree() {
        QueryWrapper<SysMenuEntity> wrapper = Wrappers.query();
        List<SysMenuEntity> roots = menuMapper.listMenu(wrapper.eq("m.parent_id", 0L).eq("m.deleted", 0));
        List<RouteVO> routes = new ArrayList<>();
        menu(roots, routes);
        return routes;
    }

    @Override
    public List<MenuVO> getMenuList() {
        return menuMapper.selectMenuOptions();
    }

    @Override
    public String selectPermByPathAndType(String path, String method) {
        return menuMapper.selectPermByPathAndType(path, method);
    }

    private void menu(List<SysMenuEntity> roots, List<RouteVO> routes) {
        if (roots != null && !roots.isEmpty()) {
            for (SysMenuEntity parent : roots) {
                RouteVO root = route(parent);

                if (parent.getType() == 0 && parent.getParentId() == 0) {
                    routes.add(root);
                }
                QueryWrapper<SysMenuEntity> wrapper = Wrappers.query();
                List<SysMenuEntity> children = menuMapper.listMenu(wrapper.eq("m.parent_id", parent.getId()).ne("m.type", 2).eq("m.deleted", 0));
                if (children != null && !children.isEmpty()) {

                    List<RouteVO> childrenRoute = childRoute(children);

                    root.setChildren(childrenRoute);

                    menu(children, routes);
                }
            }
        }
    }

    private RouteVO route(SysMenuEntity menu) {
        RouteVO root = new RouteVO();
        root.setPath(menu.getPath());
        root.setName(menu.getName());
        root.setComponent(menu.getComponent());

        RouteVO.Meta meta = new RouteVO.Meta();
        meta.setTitle(menu.getTitle());
        meta.setIcon(menu.getIcon());
        meta.setShowLink(menu.getShowLink());
        meta.setRoles(menu.getRoles().stream().map(SysRoleEntity::getCode).collect(Collectors.toList()));//菜单里面需要有哪些角色才可以访问:前端拿到角色和登录账号的角色进行匹配
        meta.setFrameSrc(menu.getFrameSrc());
        meta.setKeepAlive(menu.getKeepAlive());
        //前端的按钮是否展示:通过返回给前端路由中是否有该权限按钮标识来判断是否需要展示该按钮 前端通过hasAuth来判断
        //所以这里放的是用户的权限标识
        //另外:权限还需要配置在菜单表中 例:菜单/menu/add-->权限menu:add 用户:admin menu:add 这时候接口/menu/add需要用户admin具有menu:add才能访问
        String auths = menu.getBtnPerm();
        meta.setAuths(Collections.singletonList(auths));

        root.setMeta(meta);

        return root;
    }

    private List<RouteVO> childRoute(List<SysMenuEntity> menus) {
        List<RouteVO> children = new ArrayList<>();

        if (menus != null && !menus.isEmpty()) {
            for (SysMenuEntity menu : menus) {
                RouteVO child = route(menu);
                children.add(child);
            }
        }

        return children;
    }
}
